#include <iostream>
#include <functional>

namespace ptr
{
    template <class T>
    class share_ptr
    {
    public:
        explicit share_ptr(T *obj)
            : _ptr(obj), _count(new int(1))
        {
        }

        template <class DEL>
        share_ptr(T *obj, DEL del)
            : _del(del), _ptr(obj), _count(new int(1))
        {
        }

        T &operator*()
        {
            return *_ptr;
        }

        T *operator->()
        {
            return _ptr;
        }

        T *operator[](size_t index)
        {
            return _ptr + index;
        }

        void release()
        {
            _del(_ptr);
            delete (_count);
            _ptr = nullptr;
            _count = nullptr;
        }

        share_ptr &operator=(const share_ptr &obj)
        {
            if (obj._ptr != _ptr)
            {
                *_count -= 1;
                if (*_count == 0)
                {
                    release();
                }
                _count = obj._count;
                (*_count) += 1;
                _ptr = obj._ptr;
            }

            return *this;
        }

        T *use_ptr() const
        {
            return _ptr;
        }

        int use_count() const
        {
            return *_count;
        }

        ~share_ptr()
        {
            *_count -= 1;
            if (*_count == 0)
            {
                release();
                std::cout << "释放资源" << std::endl;
            }
            //std::cout << *_count << std::endl;
            std::cout << "析构函数调用" << std::endl;
        }

    private:
        T *_ptr = nullptr;
        int *_count = 0;
        std::function<void(T *)> _del = [](T *_ptr)
        { delete _ptr; };
    };
}

// class Data
// {
// public:
//     Data()
//      :arr(new int[10])
//      ,count(new int(10)
//      {}

// private:
//     int *arr;
//     int *count;
// };

void del(int* ptr)
{
    delete[] ptr;
    std::cout << "释放数组" << std::endl;
}

int main()
{
    int *arr = new int[10];
    int *arr2 = new int[10];
    ptr::share_ptr<int> p1(arr, del);
    ptr::share_ptr<int> p2(arr2, del);
    std::cout << "+++++++++" << std::endl;
    p2 = p1;
    std::cout << "+++++++++" << std::endl;
    return 0;
}